package chapter24;

import java.io.File;
import java.util.concurrent.TimeUnit;

/**
 * @author lzy
 * @version v1.0
 * Create DateTime: 2019/2/27 22:42
 */
public class HotDeployDemo {
    private static final String CLASS_NAME = "chapter24.HelloImpl";
    private static final String FILE_NAME = "chapter24.HelloImpl.class";
    private static volatile IHelloService helloService;

    public static void client() {
        Thread thread = new Thread(() -> {
            while (true) {
                IHelloService service = getHelloService();
                service.sayHello();
                try {
                    TimeUnit.MILLISECONDS.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        thread.start();
    }

    public static void monitor() {
        Thread thread = new Thread() {
            private long lastModified = new File(FILE_NAME).lastModified();

            @Override
            public void run() {
                while (true) {
                    try {
                        TimeUnit.MILLISECONDS.sleep(100);
                        long now = new File(FILE_NAME).lastModified();
                        if (now != lastModified) {
                            System.out.println("reload class file");
                            lastModified = now;
                            reloadService();
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
    }

    public static IHelloService getHelloService() {
        if (helloService != null) {
            return helloService;
        }

        synchronized (HotDeployDemo.class) {
            if (helloService == null) {
                helloService = createService();
            }

            return helloService;
        }
    }

    private static IHelloService createService() {
        MyClassLoader classLoader = new MyClassLoader("class/");
        try {
            Class<?> cls = classLoader.loadClass(CLASS_NAME);
            if (cls != null) {
                return (IHelloService) cls.newInstance();
            }
        } catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) {
            throw new RuntimeException("create hello service exception", e);
        }
        return null;
    }

    private static void reloadService() {
        helloService = createService();
    }
}
